/*
* EnthalpyService.java
* Created on  202015/6/4 10:01
* 版本       修改时间          作者      修改内容
* V1.0.1    202015/6/4       panzhuowen    初始版本
*
*/

package com.infitecs.eyas.enthalpy.service;

import com.infitecs.eyas.constant.Constant;
import com.infitecs.eyas.enthalpy.dao.EnthalpyDao;
import com.infitecs.eyas.enthalpy.model.Enthalpy;
import com.infitecs.eyas.expression.dao.ExpressionDao;
import com.infitecs.eyas.expression.model.Formula;
import com.infitecs.eyas.util.DoubleUtil;
import com.infitecs.eyas.util.ExpressionFactoryEnthalpy;
import com.infitecs.eyas.util.Parameter;
import com.infitecs.eyas.util.ParametersUtil;
import fr.expression4j.core.Expression;
import fr.expression4j.core.Parameters;
import fr.expression4j.core.exception.EvalException;
import fr.expression4j.core.exception.ParsingException;
import fr.expression4j.factory.ExpressionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 类的描述信息
 *
 * @author panzhuowen
 * @version 1.0.1
 */
@Service
public class EnthalpyService {

    @Autowired
    private EnthalpyDao enthalpyDao;

    @Autowired
    private ExpressionDao expressionDao;

    public Enthalpy getEnthalpy(int caseId) {
        return enthalpyDao.getEnthalpy(caseId);
    }

    public void insertCaseId(int caseId) {
        enthalpyDao.insertCaseId(caseId);
    }

    public void saveB2(double b2, int caseId) {
        enthalpyDao.saveB2(b2, caseId);
    }

    public void saveC2(double c2, int caseId) {
        enthalpyDao.saveC2(c2, caseId);
    }

    public Map<String, Double> culAndSaveD2(double c2, int caseId) throws ParsingException, EvalException {
        Map<String, Double> result = new HashMap<>();
        Formula formula = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_1);
        Expression expression = ExpressionFactory.createExpression(formula.getParamer() + formula.getFormulaDescription());
        Set<Parameter> parameter = new HashSet<>();
        parameter.add(new Parameter("C2", c2));
        Parameters parameters = ParametersUtil.getParameters(parameter);
        double d2 = expression.evaluate(parameters).getRealValue();
        enthalpyDao.saveD2(d2, caseId);
        double e2 = culE2(d2, caseId);
        result.put("d2", DoubleUtil.getInstance().get3Double(d2));
        result.put("e2", DoubleUtil.getInstance().get4Double(e2));
        return result;
    }

    public Map<String, Double> culH2(double b2, int caseId) {
        Map<String, Double> result = new HashMap<>();
        Expression expression = null;
        double temp = 0;
        try {
            expression = ExpressionFactory.createExpression("y()=611.213*10^(-6)");
            temp = expression.evaluate(ExpressionFactory.createParameters()).getRealValue();
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (b2 >= temp && b2 <= 22.064) {
            Formula formula = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_2);
            String exp = formula.getParamer() + formula.getFormulaDescription();
            Expression expression1 = null;
            try {
                expression1 = ExpressionFactory.createExpression(exp);
            } catch (ParsingException e) {
                e.printStackTrace();
            }
            Set<Parameter> parametersSet = new HashSet<>();
            parametersSet.add(new Parameter("B2", b2));
            Parameters parameters = ParametersUtil.getParameters(parametersSet);
            double g2 = 0;
            try {
                g2 = expression1.evaluate(parameters).getRealValue();
            } catch (EvalException e) {
                e.printStackTrace();
            }
            Formula formula1 = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_3);
            Expression expression2 = null;
            try {
                expression2 = ExpressionFactory.createExpression(formula1.getParamer() + formula1.getFormulaDescription());
            } catch (ParsingException e) {
                e.printStackTrace();
            }
            Set<Parameter> parametersSet1 = new HashSet<>();
            parametersSet1.add(new Parameter("G2", g2));
            Parameters parameters1 = ParametersUtil.getParameters(parametersSet1);
            double h2 = 0;
            try {
                h2 = expression2.evaluate(parameters1).getRealValue();
            } catch (EvalException e) {
                e.printStackTrace();
            }
            result.put("g2", DoubleUtil.getInstance().get3Double(g2));
            result.put("h2", DoubleUtil.getInstance().get3Double(h2));
            enthalpyDao.saveG2(DoubleUtil.getInstance().get3Double(g2), caseId);
            enthalpyDao.saveH2(DoubleUtil.getInstance().get3Double(h2), caseId);
            return result;
        } else if ((b2 > 22.064 && b2 < 100) || (b2 > 0 && b2 < temp)) {
            result.put("g2", 0.0);
            result.put("h2", 0.0);
            return result;
        } else {
            result.put("g2", 0.0);
            result.put("h2", 0.0);
            return result;
        }
    }

    private double culE2(double d2, int caseId) {
        double e2 = 0.0;
        if (d2 >= 273.15 && d2 <= 647.096) {
            Formula formula = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_4);
            String exp = formula.getParamer() + formula.getFormulaDescription();
            try {
                Expression expression = ExpressionFactory.createExpression(exp);
                Set<Parameter> param = new HashSet<>();
                param.add(new Parameter("D2", d2));
                e2 = expression.evaluate(ParametersUtil.getParameters(param)).getRealValue();
                enthalpyDao.saveE2(DoubleUtil.getInstance().get3Double(e2), caseId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (d2 > 647.096 || d2 < 273.15) {
            return -1.0;
        }
        return e2;
    }

    private double culE2(double d2) {
        double e2 = 0.0;
        if (d2 >= 273.15 && d2 <= 647.096) {
            Formula formula = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_4);
            String exp = formula.getParamer() + formula.getFormulaDescription();
            try {
                Expression expression = ExpressionFactory.createExpression(exp);
                Set<Parameter> param = new HashSet<>();
                param.add(new Parameter("D2", d2));
                e2 = expression.evaluate(ParametersUtil.getParameters(param)).getRealValue();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        if (d2 > 647.096 || d2 < 273.15) {
            return -1.0;
        }
        return e2;
    }

    public Map<String, Double> culF2AndI2(int caseId) throws ParsingException, EvalException {
        Map<String, Double> result = new HashMap<>();
        Enthalpy enthalpy = enthalpyDao.getEnthalpy(caseId);
        double b2 = enthalpy.getB2();
        double d2 = enthalpy.getD2();
        boolean flag1 = b2 > 16.5292 && b2 < 100;
        boolean flag2 = d2 > 623.15 && d2 < 863.15;
        if (flag1) {
            Formula formula5 = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_5);
            Expression expression5 = ExpressionFactory.createExpression(formula5.getParamer() + formula5.getFormulaDescription());
            Set<Parameter> param6 = new HashSet<>();
            param6.add(new Parameter("B2", b2));
            Parameters parameters6 = ParametersUtil.getParameters(param6);
            double f2 = expression5.evaluate(parameters6).getRealValue();
            enthalpyDao.saveI2(DoubleUtil.getInstance().get3Double(f2), caseId);

            result.put("i2", DoubleUtil.getInstance().get3Double(f2));
        }
        if (flag2) {
            Formula formula6 = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_6);
            Expression expression6 = ExpressionFactory.createExpression(formula6.getParamer() + formula6.getFormulaDescription());
            Set<Parameter> param5 = new HashSet<>();
            param5.add(new Parameter("D2", d2));
            Parameters parameters5 = ParametersUtil.getParameters(param5);
            double i2 = expression6.evaluate(parameters5).getRealValue();
            enthalpyDao.saveF2(DoubleUtil.getInstance().get3Double(i2), caseId);
            result.put("f2", DoubleUtil.getInstance().get3Double(i2));
        }
        return result;



    }

    public Map<String, Double> culF2AndI2(double b2,double d2) throws ParsingException, EvalException {
        Map<String, Double> result = new HashMap<>();
        boolean flag1 = b2 > 16.5292 && b2 < 100;
        boolean flag2 = d2 > 623.15 && d2 < 863.15;
        if (flag1) {
            Formula formula5 = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_5);
            Expression expression5 = ExpressionFactory.createExpression(formula5.getParamer() + formula5.getFormulaDescription());
            Set<Parameter> param6 = new HashSet<>();
            param6.add(new Parameter("B2", b2));
            Parameters parameters6 = ParametersUtil.getParameters(param6);
            double f2 = expression5.evaluate(parameters6).getRealValue();
            result.put("i2", DoubleUtil.getInstance().get3Double(f2));
        }
        if (flag2) {
            Formula formula6 = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_6);
            Expression expression6 = ExpressionFactory.createExpression(formula6.getParamer() + formula6.getFormulaDescription());
            Set<Parameter> param5 = new HashSet<>();
            param5.add(new Parameter("D2", d2));
            Parameters parameters5 = ParametersUtil.getParameters(param5);
            double i2 = expression6.evaluate(parameters5).getRealValue();
            result.put("f2", DoubleUtil.getInstance().get3Double(i2));
        }
        return result;

    }

    public double culB6(int caseId) throws ParsingException, EvalException {
        double b6 = 0;
        Enthalpy enthalpy = enthalpyDao.getEnthalpy(caseId);
        double b2 = enthalpy.getB2();
        double d2 = enthalpy.getD2();
        boolean flag1 = (d2 >= 237.15 && d2 <= 623.15 && b2 > 0 && b2 < enthalpy.getE2());
        boolean flag2 = (d2 > 623.15 && d2 <= 863.15 && b2 > 0 && b2 <= enthalpy.getF2());
        boolean flag3 = (d2 > 863.15 && d2 <= 1073.15 && b2 > 0 && b2 <= 100);
        if (d2 >= 237.15 && d2 <= 623.15 && b2 >= enthalpy.getE2() && b2 <= 100) {
            b6 = culB3(b2, d2);
        } else if (flag1 || flag2 || flag3) {
            b6 = culB4(b2, d2);
        } else if (d2 >= 623.15 && d2 <= enthalpy.getI2() && b2 > enthalpy.getF2() && b2 <= 100) {
            b6 = culB5(enthalpy);
        }
        enthalpyDao.saveB6(DoubleUtil.getInstance().get3Double(b6), caseId);
        return DoubleUtil.getInstance().get3Double(b6);
    }

    public double culB6(double b2, double d2) throws ParsingException, EvalException {
        double b6 = 0;
        double e2 = culE2(d2);
        Map<String,Double> map = culF2AndI2(b2, d2);
        double f2 =map.get("f2")==null? -1.0:map.get("f2");
        boolean flag1 = (d2 >= 237.15 && d2 <= 623.15 && b2 > 0 && b2 < e2);
        boolean flag2 = (d2 > 623.15 && d2 <= 863.15 && b2 > 0 && b2 <= f2);
        boolean flag3 = (d2 > 863.15 && d2 <= 1073.15 && b2 > 0 && b2 <= 100);
        if (d2 >= 237.15 && d2 <= 623.15 && b2 >= e2 && b2 <= 100) {
            b6 = culB3(b2, d2);
        } else if (flag1 || flag2 || flag3) {
            b6 = culB4(b2, d2);
        } else {
            Enthalpy enthalpy = new Enthalpy();
            enthalpy.setB2(b2);
            enthalpy.setD2(d2);
            enthalpy.setE2(culE2(d2));
            b6 = culB5(enthalpy);
        }
        return DoubleUtil.getInstance().get3Double(b6);
    }

    private double culB3(double b2, double d2) throws ParsingException, EvalException {
        Formula formula = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_7);
        Expression expression = ExpressionFactory.createExpression(formula.getParamer() + formula.getFormulaDescription());
        Set<Parameter> param = new HashSet<>();
        param.add(new Parameter("B2", b2));
        param.add(new Parameter("D2", d2));
        Parameters parameters = ParametersUtil.getParameters(param);
        double b3 = expression.evaluate(parameters).getRealValue();
        return DoubleUtil.getInstance().get3Double(b3);
    }

    private double culB4(double b2, double d2) throws ParsingException, EvalException {
        Formula formula = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_8);
        Expression expression = ExpressionFactory.createExpression(formula.getParamer() + formula.getFormulaDescription());
        Set<Parameter> param = new HashSet<>();
        param.add(new Parameter("B2", b2));
        param.add(new Parameter("D2", d2));
        Parameters parameters = ParametersUtil.getParameters(param);
        double b4 = expression.evaluate(parameters).getRealValue();
        return DoubleUtil.getInstance().get3Double(b4);
    }

    private double culB5(Enthalpy enthalpy) throws ParsingException, EvalException {
        double pold, p,pnew=0.0,p1;
        if (enthalpy.getB2() < enthalpy.getE2() && enthalpy.getD2() >= 623.15 && enthalpy.getD2() <= 647.096) {
            pold = 100;
        } else {
            pold = 600;
        }
        long time1 = System.currentTimeMillis();
        Formula formulaAdd1 = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_ADD_1);
        Expression expressionAdd1 = ExpressionFactoryEnthalpy.createExpression(formulaAdd1.getParamer() + formulaAdd1.getFormulaDescription());
        Formula formulaAdd2 = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_ADD_2);
        Expression expressionAdd2 = ExpressionFactoryEnthalpy.createExpression(formulaAdd2.getParamer() + formulaAdd2.getFormulaDescription());
        Expression expression = ExpressionFactoryEnthalpy.createExpression("y()=10^(-12)");
        while (true) {
            p = pold / 322;
            Set<Parameter> param1 = new HashSet<>();
            param1.add(new Parameter("F5",p));
            param1.add(new Parameter("D2",enthalpy.getD2()));
            param1.add(new Parameter("D5",pold));
            Parameters parameters1 = ParametersUtil.getParameters(param1);
            p1 = expressionAdd1.evaluate(parameters1).getRealValue();
            Set<Parameter> param2 = new HashSet<>();
            param2.add(new Parameter("G5",p1));
            param2.add(new Parameter("B2",enthalpy.getB2()));
            param2.add(new Parameter("F5",p));
            param2.add(new Parameter("D2",enthalpy.getD2()));
            param2.add(new Parameter("D5",pold));
            Parameters parameters2 = ParametersUtil.getParameters(param2);
            pnew = expressionAdd2.evaluate(parameters2).getRealValue();
            if (Math.abs(pnew-pold) < expression.evaluate(ExpressionFactory.createParameters()).getRealValue()) {
                break;
            } else {
                pold = pnew;
            }
            long time2 = System.currentTimeMillis();
            long time3 = time2-time1;
            if(time3/1000>2){
                throw new RuntimeException();
            }
        }
        Formula formula = expressionDao.getFormulaByName(Constant.FORMULA_ENTHALPY_9);
        Expression expression1 = ExpressionFactoryEnthalpy.createExpression(formula.getParamer() + formula.getFormulaDescription());
        Set<Parameter> param = new HashSet<>();
        param.add(new Parameter("H5",pnew));
        param.add(new Parameter("D2",enthalpy.getD2()));
        Parameters parameters = ParametersUtil.getParameters(param);
        double b5 = expression1.evaluate(parameters).getRealValue();

        return DoubleUtil.getInstance().get3Double(b5);
    }

}
